#include <stdio.h>
#include <string.h>
#include "iot_i2c.h"    //I2C 接口
#include "iot_errno.h"  //错误码管理
#include "aht20.h"
#include <unistd.h>  // 可选，若不使用usleep可删

#define AHT20_I2C_PORT       EI2C0_M2   //定义 AHT20 传感器使用的 I2C 硬件接口
#define AHT20_I2C_ADDR       0x38       //定义 AHT20 传感器的 I2C 设备地址（7 位地址格式）
#define AHT20_CMD_INIT       0xBE       //定义 AHT20 初始化命令
#define AHT20_CMD_TRIGGER    0xAC       //定义 AHT20 触发测量命令

// 温湿度数据的合法范围宏定义
#define AHT20_TEMP_MIN     (-40.0f)
#define AHT20_TEMP_MAX     (85.0f)
#define AHT20_HUMI_MIN     (0.0f)
#define AHT20_HUMI_MAX     (100.0f)

/***************************************************************
* 函数名称: aht20_write_cmd
* 说    明: 向AHT20发送命令
* 参    数: cmd：命令数据；len：长度
* 返 回 值: 写入结果
***************************************************************/
static int aht20_write_cmd(uint8_t *cmd, uint32_t len)
{
    return IoTI2cWrite(AHT20_I2C_PORT, AHT20_I2C_ADDR, cmd, len);
}


/***************************************************************
* 函数名称: aht20_init
* 说    明: 初始化AHT20传感器
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void aht20_init(void)
{
    uint32_t ret;

    // 初始化I2C接口
    ret = IoTI2cInit(AHT20_I2C_PORT, EI2C_FRE_100K);    //波特率为400kHz：表示每秒能传输400,000个符号
    if (ret != IOT_SUCCESS) {
        //初始化失败
        printf("[AHT20] I2C init failed!\n");
        return;
    }

    // 初始化命令：0xBE + 0x08 + 0x00
    uint8_t init_cmd[] = {AHT20_CMD_INIT, 0x08, 0x00};  //
    ret = aht20_write_cmd(init_cmd, 3);
    if (ret != IOT_SUCCESS) {
        printf("[AHT20] initialization command failed!\n");
        return;
    }
    usleep(20000); // 等待10ms，等待 AHT20 完成初始化校准

    // 可选：验证设备是否响应
    uint8_t check_cmd[] = {0x71};  // 一个简单的读取命令，具体命令可以参考AHT20文档
    ret = aht20_write_cmd(check_cmd, 1);
    if (ret != IOT_SUCCESS) {
        printf("[AHT20] check command failed!\n");
        return;
    }

    printf("[AHT20] initialized successfully.\n");
}


/***************************************************************
* 函数名称: aht20_read_data
* 说    明: 读取AHT20温湿度数据
* 参    数: dat：返回的温湿度数据 [温度，湿度]
* 返 回 值: 无
***************************************************************/
//ant20内部 已集成 CRC 校验机制，在芯片层做了错误检测和校正，所以我们读取到的是已经处理好的稳定数据
void aht20_read_data(double *dat)
{   
    int ret, retry = 0; 

    uint8_t trigger_cmd[] = {AHT20_CMD_TRIGGER, 0x33, 0x00};//触发测量的命令数组：0xAC（命令头） + 0x33 + 0x00（高精度模式）
    //存储从传感器读取的 6 字节原始数据（温度 3 字节 + 湿度 3 字节）
    // Byte 0	状态字	最高位表示忙状态（可忽略）
    // Byte 1-2	湿度数据（20位）	高8位 + 低8位 + 共享4位
    // Byte 3-5	温度数据（20位）	共享4位 + 中8位 + 低8位
    uint8_t read_buf[6] = {0};  

    // 发送测量命令
    aht20_write_cmd(trigger_cmd, 3);
    usleep(80000); // 等待80ms，AHT20 需要约 80ms 完成一次高精度测量（数据手册要求）

    // 读取6字节原始数据
    ret = IoTI2cRead(AHT20_I2C_PORT, AHT20_I2C_ADDR, read_buf, 6);

    
   // 多次尝试读取数据
    for (retry = 0; retry < 5; retry++) {
        ret = IoTI2cRead(AHT20_I2C_PORT, AHT20_I2C_ADDR, read_buf, sizeof(read_buf));
        if (ret == IOT_SUCCESS) break;
        printf("[AHT20] Read failed, retry %d\n", retry + 1);
        LOS_Msleep(20);
    }

    if (retry > 3) {
        printf("[AHT20] read failed after retries.\n");
        return;
    }

    // 检查状态位 bit[7] 是否为0，表示数据准备好
    if (read_buf[0] & 0x80) {
        printf("[AHT20] is busy or data not ready.\n");
        dat[0] = dat[1] = -100.0;
        return;
    }

    // 数据解析
    uint32_t raw_humi = ((uint32_t)(read_buf[1]) << 12) | ((uint32_t)(read_buf[2]) << 4) | (read_buf[3] >> 4);
    uint32_t raw_temp = ((uint32_t)(read_buf[3] & 0x0F) << 16) | ((uint32_t)(read_buf[4]) << 8) | read_buf[5];
    
      // 单位换算
    double temp = ((double)raw_temp * 200 / 1048576) - 50;
    double humi = ((double)raw_humi * 100) / 1048576;

    // 合理性判断
    if (temp < -40 || temp > 85 || humi < 0 || humi > 100) {
        printf("[AHT20] Data out of range. Temp: %.2f °C, RH: %.2f %%\n", temp, humi);
        return;
    }

    // 返回结果
    dat[0] = temp;
    dat[1] = humi;
}

